﻿using System;
using System.IO;
using BuildScripts;
using Flubu;
using Flubu.Builds;

//css_ref bin\Debug\Flubu.dll;
//css_ref ..\lib\ICSharpCode.SharpZipLib.2.0\ICSharpCode.SharpZipLib.dll;
//css_ref ProjectPilot.BuildScripts.dll;
//css_import HudsonExtensionsBuildRunner.cs;
//css_import PackageMaster.cs;

namespace Brejc.Geo.BuildScripts
{
    public class BuildScript
    {
        public static int Main(string[] args)
        {
            using (HudsonExtensionsBuildRunner runner = new HudsonExtensionsBuildRunner ("Quiki"))
            {
                try
                {
                    runner
                        .SetLibrariesDirectory(@"lib")
                        .AddTarget("load.solution").SetAsHidden().Do(TargetLoadSolution);
                    runner.AddTarget("compile")
                        .SetDescription("Compiles the VS solution and runs FxCop analysis on it")
                        .Do(TargetCompile).DependsOn("load.solution");
                    runner.AddTarget ("unit.tests")
                        .SetDescription ("Runs unit tests on the project")
                        .Do (r =>
                                 {
                                     r.RunTests ("Quiki.Tests", false); 
                                 }).DependsOn ("load.solution");
                    runner.AddTarget("package")
                        .SetDescription("Packages all the build products into ZIP files")
                        .Do(TargetPackage).DependsOn("load.solution");
                    runner.AddTarget("rebuild")
                        .SetDescription("Rebuilds the project, runs tests and packages the build products.")
                        .SetAsDefault().DependsOn("compile", "unit.tests", "docs", "package");
                    runner.AddTarget ("update.lib.flubu")
                        .SetDescription ("Updates the lib directory with the latest versions of Flubu libraries")
                        .Do (r => TargetUpdateLib (r, @"D:\MyStuff\BuildArea\Builds\ProjectPilot\packages\Flubu\Flubu-latest.zip", @"lib\Flubu"));
                    runner.AddTarget("docs")
                        .SetDescription("Generates Quiki documentation using Quiki :)")
                        .Do(r => TargetDocs(r, false)).DependsOn("load.solution");
                    runner.AddTarget("docs.debug")
                        .SetDescription("Generates Quiki documentation using Quiki (in Debug mode)")
                        .Do(r => TargetDocs(r, true)).DependsOn("load.solution");

                    // actual run
                    if (args.Length == 0)
                        runner.RunTarget(runner.DefaultTarget.TargetName);
                    else
                        runner.RunTarget(args[0]);

                    runner
                        .Complete();

                    return 0;
                }
                catch (RunnerFailedException)
                {
                    return 1;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    return 1;
                }
                finally
                {
                    runner.MergeCoverageReports();
                    runner.CopyBuildLogsToCCNet();
                }
            }
        }

        private static void TargetCompile(ConcreteBuildRunner runner)
        {
            runner
                .PrepareBuildDirectory()
                .SetCompanyInfo(
                "Igor Brejc",
                "Copyright (C) 2010 Igor Brejc",
                String.Empty)
                .CleanOutput();

            string commonAssemblyInfoFileName = Path.Combine(runner.ProductRootDir, "CommonAssemblyInfo.cs");

            runner.ScriptExecutionEnvironment.LogMessage("CommonAssemblyInfo.cs path: '{0}'", commonAssemblyInfoFileName);
            runner
                .GenerateCommonAssemblyInfo()
                .CompileSolution();

            runner
                .FxCop();
        }

        private static void TargetLoadSolution(ConcreteBuildRunner runner)
        {
            HudsonExtensionsBuildRunner extendedRunner = (HudsonExtensionsBuildRunner)runner;

            extendedRunner
                .LoadSolution("Quiki.sln");
            extendedRunner
                .HudsonFetchBuildVersion ();
        }

        private static void TargetPackage(ConcreteBuildRunner runner)
        {
            PackageMaster master = new PackageMaster(runner, @"Builds\Packages");
            master
                .CleanPackagingTempDirectory()
                .AddDir (GetConsoleOutputPath(runner))
                    .ToDir("Quiki-{0}", runner.BuildVersion)
                    .Exclude ("log4net.xml")
                    .Exclude ("NVelocity.xml")
                    .Exclude ("PowerCollections.xml")
                    .Exclude ("QuickGraph.xml")
                    .Commit ()
                .AddDir("Docs")
                    .ToDir("docs_source")
                    .Commit()
                .AddDir(PathBuilder.New(runner.BuildPackagesDir).Add("Docs"))
                    .ToDir("docs")
                    .Commit()
                .Zip ("Quiki-{0}.zip", runner.BuildVersion);

            //runner
            //    .BuildProducts
            //    .AddProject("core", "Quiki.Console", String.Empty, false);
            //    //.AddFile ("core", "ChangeLog.txt", "ChangeLog.txt")
            //    //.AddFile ("core", "Copying.txt", "Copying.txt")
            //    //.AddFile ("core", "Copying.txt", "licenses/license-GroundTruth.txt")
            //    //.AddFile ("core", "Readme.txt", "Readme.txt")
            //    //.AddFile ("misc", @"..\lib\Brejc.Geo\Copying.txt", @"licenses\license-Brejc.Geo.txt")
            //    //.AddFile ("misc", @"..\lib\Castle\ASL - Apache Software Foundation License.txt", @"licenses\license-Castle.txt")
            //    //.AddFile ("misc", @"..\lib\ICSharpCode.SharpZipLib.2.0\COPYING.txt", @"licenses\license-SharpLibZip.txt")
            //    //.AddFile ("misc", @"..\lib\log4net-1.2.10\log4net.LICENSE.txt", @"licenses\license-log4net.txt")
            //    //.AddFile ("misc", @"..\lib\PowerCollections\Binaries\License.txt", @"licenses\license-PowerCollections.txt")
            //    //.AddFile ("misc", @"..\lib\QuickGraph\license.txt", @"licenses\license-QuickGraph.txt");


            //runner
            //    .PackageBuildProduct ("Quiki-{1}.zip", "Quiki-{1}", "core", "misc");
            //    //.CopyBuildProductToCCNet (@"packages\GroundTruth\GroundTruth-latest.zip")
            //    //.CopyBuildProductToCCNet (@"packages\GroundTruth\{2}.{3}\{4}");
        }

        private static PathBuilder GetConsoleOutputPath(ConcreteBuildRunner runner)
        {
            return PathBuilder.New("Quiki.Console").Add(runner.GetProjectOutputPath("Quiki.Console"));
        }

        private static void TargetUpdateLib (
            ConcreteBuildRunner runner,
            string libBuildPackageFileName,
            string libIncludeDirectory)
        {
            PathBuilder tempDir = PathBuilder.New (runner.BuildDir).Add ("Temp");
            runner
                .DeleteDirectory (tempDir, false)
                .EnsureDirectoryPathExists (tempDir, false);

            runner.Unzip (
                libBuildPackageFileName,
                tempDir);

            string[] dirs = Directory.GetDirectories (tempDir);
            string zipDir = Path.GetFileName (dirs[0]);
            runner.CopyDirectoryStructure (tempDir.Add (zipDir), libIncludeDirectory, true);
        }

        private static void TargetDocs(ConcreteBuildRunner runner, bool useDebugBin)
        {
            runner.ProgramRunner
                .AddArgument("html")
                .AddArgument(@"-i=Docs")
                .AddArgument(@"-t=Docs\template.vm.html")
                .AddArgument(@"-o={0}\docs", runner.BuildPackagesDir)
                .AddArgument(@"-lf=Quiki.css");

            if (useDebugBin)
                runner.ProgramRunner.Run
                    (PathBuilder.New("Quiki.Console").Add(@"bin\Debug").Add("Quiki.Console.exe"));
            else
                runner.ProgramRunner.Run(GetConsoleOutputPath(runner).Add("Quiki.Console.exe"));
        }
    }
}